package com.huaxin.dss2.util;

import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.huaxin.dss2.data.bean.FullCodeBean;
import com.huaxin.dss2.data.bean.properties.HxDssProperties;
import java.net.Proxy;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


/**
 * 全局常量类
 * @author luqing
 * @date 2018/5/10 15:21
 */
@Component
public class Constant {

    /**
     * 全局使用的线程池
     */
    public static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("dss-pool-%d").build();
    public static final ExecutorService GLOBAL_THREAD =  new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(),THREAD_FACTORY);;

    private static HxDssProperties properties;
    private static FullCodeBean fullCodeBean;


    public static FullCodeBean getFullCode(){
        return fullCodeBean;
    };

    public static HxDssProperties getProperties(){
        return properties;
    }

    public static LoggerType loggerType = LoggerType.console;

    /**
     * 截取三段，不是三段的数据为错误数据
     */
    @Autowired
    private void setProperties(HxDssProperties properties) {
        Constant.properties = properties;
        setFullCodeBean(new FullCodeBean());
    }

    private void setFullCodeBean(FullCodeBean fullCodeBean){
        String fullCodeFormatter = properties.getFullCodeFormatter() ;
        //分隔编码
        String[] split = fullCodeFormatter.split("_");

        fullCodeBean.setFracDigitsLength(split.length);
        Map<String,Integer> map = Maps.newHashMap();
        for (int i=0;i<fullCodeBean.getFracDigitsLength();i++){
            map.put(split[i],i);
        }
        fullCodeBean.setStationIndex(map.get("stationCode"));
        fullCodeBean.setDataItemIndex(map.get("dataItemId"));
        fullCodeBean.setDataCodeIndex(map.get("dataCode"));
        fullCodeBean.setBoxUidIndex(map.get("boxUid"));
        Constant.fullCodeBean = fullCodeBean;
    }

    /**
     * 公司名称，差异化标志
     */
//    public static final String COMPANY_NAME = PropertiesUtil.getString("huaxin.dss.companyName");

    /**
     * 数据源类型，差异化标志
     */
//    public static final String DATA_TYPE = PropertiesUtil.getString("huaxin.dss.dataType");

    /**
     * 是否使用dataItemId true:原始dataItemId，false:1
     */
//    public static final Boolean USE_DATA_ITEM_ID = PropertiesUtil.getBoolean("huaxin.dss.useDataItemId");

//    public static final String DATA_VALUE_TABLE_NAME = PropertiesUtil.getString("huaxin.dss.dataValueTableName");

    /**
     * 代理服务器配置
     */
    public final static Proxy PROXY = null;


    /**
     * @author luqing
     * fox盒子状态
     * 详细部分见fbox 文档v1.2.2 9.4 FBox状态变更推送
     */
    public enum FBoxState{

        /**
         * 未知状态
         */
        UN_KNOWN(0,"未知"),

        /**
         * 在线状态
         */
        ON_LINE(1,"在线"),

        /**
         * 超时状态
         */
        TIME_OUT(2,"超时"),

        /**
         * 掉线状态
         */
        LOST_CONNECTION(3,"掉线"),

        /**
         * 其它不存在状态
         */
        OTHER(10,"其它");

        final Integer state;
        final String desc;

        /**
         * 通过状态码获取状态对应描述
         * @param state 状态码
         * @return 状态描述 若状态码不存在返回未知状态描述
         */
        public static String getDesc(Integer state) {
            return FBoxState.getFBoxState(state).desc;
        }

        /**
         * 通过状态码获取对应枚举
         * @param state 状态码
         * @return 状态枚举 若状态不存在返回未知状态枚举
         */
        public static FBoxState getFBoxState(Integer state){
            for (FBoxState fboxState : FBoxState.values()){
                if (Objects.equals(state,fboxState.state)){
                    return fboxState;
                }
            }

            return FBoxState.OTHER;
        }

        FBoxState(Integer state, String desc) {
            this.state = state;
            this.desc = desc;
        }
    }

    /**
     * 指标推送状态
     * 详见fbox文档 v1.2.2 9.1 实时数据推送->value对应属性->status
     */
    public enum DMonUpdateValueStatus{

        /**
         * 指标无数据
         */
        NO_VALUE(1,"无数据"),

        /**
         * 指标超时
         */
        TIME_OUT(2,"超时"),

        /**
         * 指标错误
         */
        ERROR(3,"错误"),

        /**
         * 指标Socket异常
         */
        SOCKET_EX(4,"Socket异常"),

        /**
         * 指标FDS错误
         */
        FDS_EX(5,"FDS错误"),

        /**
         * 指标未完成
         */
        UN_FINISHED(16,"未完成"),

        /**
         *
         */
        OTHER(0,"其它状态");

        final Integer status;
        final String desc;

        /**
         * 通过状态码获取状态对应描述
         * @param status 状态码
         * @return 状态描述 若状态码不存在返回未知状态描述
         */
        public static String getDesc(Integer status) {
            return DMonUpdateValueStatus.getDMonUpdateValueStatus(status).desc;
        }

        /**
         * 通过状态码获取对应枚举
         * @param status 状态码
         * @return 状态枚举 若状态不存在返回未知状态枚举
         */
        public static DMonUpdateValueStatus getDMonUpdateValueStatus(Integer status){
            for (DMonUpdateValueStatus valueStatus : DMonUpdateValueStatus.values()){
                if (Objects.equals(status,valueStatus.status)){
                    return valueStatus;
                }
            }

            return DMonUpdateValueStatus.OTHER;
        }

        DMonUpdateValueStatus(Integer status, String desc) {
            this.status = status;
            this.desc = desc;
        }
    }


    public interface DssStateType{

        /**
         * 刷新指标
         */
        Integer DATA_INFO = 0;

        /**
         * 重新开点
         */
        Integer START_BOX = 1;
    }

}
